// locutor
// (c) 2008-2009, Normen Müller, normen.mueller@gmail.com  
// $Id$
package locutor.model.parsing.grgen

import collection.mutable.HashSet

/** 
 * @author <a href="mailto:normen.mueller@googlemail.com">Normen M&#xFC;ller</a>
 * @version 0.0.2 */
private [grgen] object ExprParser {
  
  val reserved = new HashSet[String] ++ List(
    "int", "double", "float", "string",
    "true", "false", "null",
    "visited", "nameof", "typeof"    
  )
  
  val delimiters = new HashSet[String] ++ List(
    "[", "]", "(", ")",
    "!", "?", ":", ",", ".", "::", 
    "^", "&&", "||", "&", "|",
    "<<", ">>>", ">>", "+", "-", "*", "/", "%", "~",
    "<=", "<", "==", "!=", ">=", ">", "in"    
  )
  
}

private [grgen] trait ExprParser extends BaseParser {
  
  def expr: Parser[Any]          = cond_expr  
  def cond_expr: Parser[Any]     = log_or_expr ~ opt("?" ~ expr ~ ":" ~ cond_expr)  
  def log_or_expr: Parser[Any]   = log_and_expr ~ (("||" ~ log_and_expr)*)
  def log_and_expr: Parser[Any]  = bit_or_expr ~ (("&&" ~ bit_or_expr)*)
  def bit_or_expr: Parser[Any]   = bit_xor_expr ~ (("|" ~ bit_xor_expr)*)
  def bit_xor_expr: Parser[Any]  = bit_and_expr ~ (("^" ~ bit_and_expr)*)
  def bit_and_expr: Parser[Any]  = except_expr ~ (("&" ~ except_expr)*)
  def except_expr: Parser[Any]   = eq_expr ~ (("\\" ~ eq_expr)*)
  def eq_expr: Parser[Any]       = rel_expr ~ ((("==" | "!=") ~ rel_expr)*)
  def rel_expr: Parser[Any]      = shift_expr ~ ((("<=" | "<" | ">=" | ">" | "in") ~ shift_expr)*)
  def shift_expr: Parser[Any]    = add_expr ~ ((("<<" | ">>>" | ">>") ~ add_expr)*)
  def add_expr: Parser[Any]      = mul_expr ~ ((("+" | "-") ~ mul_expr)*)
  def mul_expr: Parser[Any]      = unary_expr ~ ((("*" | "%" | "/") ~ unary_expr)*)
  def unary_expr: Parser[Any]    =
    ( ("~" ~ unary_expr) | ("!" ~ unary_expr) | ("-" ~ unary_expr) | ("+" ~ unary_expr)
    | ("(" ~ ("int" | "float" | "double" | "string") ~ ")" ~ unary_expr)
    | (primary_expr ~ ((selector_expr)*))
    )
  def primary_expr: Parser[Any]  =
    ( visited_expr | name_of
    | ident | ident ~ "." ~ ident | ident ~ "::" ~ ident
    | numeric | string | "true" | "false" | "null"
    | type_of
    | "(" ~ expr ~ ")"
    )
  def visited_expr: Parser[Any]  = "visited" ~ "(" ~ ident ~ (("," ~ expr ~ ")") | ")")
  def name_of: Parser[Any]       = "nameof" ~ "(" ~ opt(ident) ~ ")"
  def type_of: Parser[Any]       = "typeof" ~ "(" ~ ident ~ ")"
  def selector_expr: Parser[Any] = (("[" ~ expr ~ "]") | ("." ~ ident ~ opt(param_expr)))
  def param_expr: Parser[Any]    = "(" ~ opt(expr ~ ("," ~ expr)*) ~ ")"  

}

/** 
 * @author <a href="mailto:normen.mueller@googlemail.com">Normen M&#xFC;ller</a>
 * @version 0.0.2 */
//private [grgen] trait ExprParser extends BaseParser {
//  
//  //def expr = bool_expr | int_expr | float_expr | string_expr | primary_expr
//  def expr = bool_expr | primary_expr
//  
////  def bool_expr: Parser[Any] = 
////    ( opt("!") ~ primary_expr ~ (("?" ~ bool_expr ~ ":" ~ bool_expr | bin_bool_operator ~ bool_expr)*)
////    | type_expr ~ compare_operator ~ type_expr
////    | expr ~ compare_operator ~ expr    
////    )
//  def bool_expr: Parser[Any] = 
//    ( opt("!") ~ primary_expr
//    | primary_expr ~ "?" ~ bool_expr ~ ":" ~ bool_expr
//    | primary_expr ~ bin_bool_op ~ bool_expr
//    | expr ~ compare_op ~ expr
//    | type_expr ~ compare_op ~ type_expr    
//    )
//  
////  def int_expr: Parser[Any] =
////    ( opt("+" | "-" | "~") ~ primary_expr ~ ((bin_int_op ~ int_expr)*)
////    | bool_expr ~ "?" ~ int_expr ~ ":" ~ int_expr   
////    )  
////  
////  def float_expr: Parser[Any] =
////    ( opt("+" | "-") ~ primary_expr ~ ((bin_float_op ~ int_expr)*)
////    | bool_expr ~ "?" ~ float_expr ~ ":" ~ float_expr
////    )
////  
////  def string_expr: Parser[Any] = primary_expr ~ (("+" ~ string_expr)*)
//  
//  def primary_expr: Parser[Any] =
//    ( numeric | string | "true" | "false" | "null"
//    | "(" ~ ("int" | "float" | "double" | "string") ~ ")" ~ primary_expr
//    | "(" ~ expr ~ ")"
//    | ident ~ opt("." ~ ident | "::" ~ ident)
//    )
//  
//  def type_expr = ("typeof" ~ "(" ~ ident ~ ")") | ident
//  
//  def compare_op = "<=" | "<" | "==" | "!=" | ">=" | ">"
//  
//  def bin_bool_op = "^" | "&&" | "||" | "&" | "|"
//  
//  def bin_int_op = ("^" | "&" | "|" | "<<" | ">>>" | ">>" | "+" | "-" | "*" | "/" | "%")
//  
//  def bin_float_op = "+" | "-" | "*" | "/" | "%"
//}
